package db

import (
	"fx_swift_ifcgate/pkg/global"
	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
	"github.com/gogf/gf/v2/database/gdb"
	"time"

	"gorm.io/gorm"
)

// GFOrm 数据库配置结构体
type DBConfig struct {
	Host             string // [Must] Host of DB. Use ip or domain: 127.0.0.1, localhost.
	Port             string // [Must] Port of DB.
	User             string // [Must] Authentication username.
	Pass             string // [Must] Authentication password.
	Name             string // [Must] Database name.
	Type             string // [Optional] DB type. Default to mysql. [mysql|sqlite|mssql|pgsql|oracle]
	Link             string
	Extra            string
	MaxIdleConnCount int           // [Optional] Max idle connection configuration. Default to 100.
	MaxOpenConnCount int           // [Optional] Max open connection configuration. Default to 1100.
	MaxConnLifetime  time.Duration // [Optional] Max connection TTL configuration. Default to 3600s.
	Debug            bool          // (Optional) Debug mode enables debug information logging and output.
	Charset          string
	CreatedAt        string
	UpdatedAt        string
	DeletedAt        string
}

type Client struct {
	db        *gorm.DB
	driver    string
	isDefault bool
}

func ReadMysqlConfig() (gdb.DB, error) {
	orm, _err := SetDB(&DBConfig{
		Type:  global.ViperObj.GetString("database.default.type"),
		Host:  global.ViperObj.GetString("database.default.host"),
		Port:  global.ViperObj.GetString("database.default.port"),
		User:  global.ViperObj.GetString("database.default.user"),
		Pass:  global.ViperObj.GetString("database.default.pass"),
		Name:  global.ViperObj.GetString("database.default.name"),
		Extra: "loc=Local&parseTime=true",
		//Link:             fmt.Sprintf("mysql:%s:%s@tcp(%s:%s)/%s?loc=Local&parseTime=true", "root", "12345678", "127.0.0.1", "3306", "fx"),
		Debug:            true,
		MaxIdleConnCount: global.ViperObj.GetInt("database.default.maxIdleConnCount"),
		MaxOpenConnCount: global.ViperObj.GetInt("database.default.maxOpenConnCount"),
		MaxConnLifetime:  time.Second * time.Duration(global.ViperObj.GetInt64("database.default.maxConnLifetime")),
		CreatedAt:        "created_at",
		UpdatedAt:        "updated_at",
		DeletedAt:        "deleted_at",
	})
	return orm, _err
}

func SetGfOrmConfig(config *DBConfig) {
	orm, err := SetDB(config)
	if err != nil {
		return
	}
	global.GFDB = orm
}

func InitGorm() {
	var db1 gdb.DB
	db1, _ = ReadMysqlConfig()
	global.GFDB = db1
}

func SetDB(config *DBConfig) (gdb.DB, error) {
	node := gdb.ConfigNode{
		Type:             "mysql",
		Host:             config.Host,
		Port:             config.Port,
		User:             config.User,
		Pass:             config.Pass,
		Name:             config.Name,
		Extra:            "loc=Local&parseTime=true",
		MaxIdleConnCount: config.MaxIdleConnCount,
		MaxOpenConnCount: config.MaxOpenConnCount,
		MaxConnLifeTime:  config.MaxConnLifetime,
		Debug:            config.Debug,
		CreatedAt:        "created_at",
		UpdatedAt:        "updated_at",
		DeletedAt:        "deleted_at",
		Charset:          "utf8mb4",
	}
	// set config
	gdb.SetConfig(gdb.Config{
		gdb.DefaultGroupName: gdb.ConfigGroup{
			node,
		},
	})
	// test connection
	orm, err := GetDBInstance()
	return orm, err
}

func GetDBInstance(name ...string) (gdb.DB, error) {
	if len(name) == 0 {
		return gdb.Instance(gdb.DefaultGroupName)
	}
	return gdb.Instance(name...)
}
